package org.lim.aiagent.advisor;

import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.client.ChatClientRequest;
import org.springframework.ai.chat.client.ChatClientResponse;
import org.springframework.ai.chat.client.advisor.api.AdvisorChain;
import org.springframework.ai.chat.client.advisor.api.BaseAdvisor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用于检查用户输入中的禁用词的顾问。
 *   禁用词语列表是从外部资源文件中加载的。
 */
@Component
public class ForbiddenWordsAdvisor implements BaseAdvisor {

    private static final Logger logger = LoggerFactory.getLogger(ForbiddenWordsAdvisor.class);

    // 使用 @Value 从 application.properties 读取配置，或使用默认值
    // 默认从 classpath 下的 forbidden-words.txt 文件加载
    @Value("classpath:forbidden-words.txt")
    private Resource forbiddenWordsResource;

    private final Set<String> forbiddenWords = new HashSet<>();

    private int order = 0;

    /**
     * 使用 @PostConstruct 注解，在依赖注入完成后，服务启动时执行此初始化方法。
     * 它负责从资源文件加载违禁词。
     */
    @PostConstruct
    public void initialize() {
        if (!forbiddenWordsResource.exists()) {
            logger.warn("违禁词文件未找到: {}", forbiddenWordsResource);
            return;
        }

        try (BufferedReader reader = new BufferedReader(new InputStreamReader(forbiddenWordsResource.getInputStream(), StandardCharsets.UTF_8))) {
            Set<String> words = reader.lines()
                    .map(String::trim)
                    .filter(line -> !line.isEmpty() && !line.startsWith("#")) // 忽略空行和注释
                    .map(String::toLowerCase) // 统一转换为小写，以便不区分大小写地匹配
                    .collect(Collectors.toSet());

            this.forbiddenWords.addAll(words);
            logger.info("成功加载 {} 个违禁词，来源: {}", this.forbiddenWords.size(), forbiddenWordsResource);

        } catch (IOException e) {
            // 在生产环境中，如果无法加载此文件，可能需要快速失败
            logger.error("加载违禁词文件时发生严重错误: {}", forbiddenWordsResource, e);
            throw new IllegalStateException("无法加载违禁词文件", e);
        }
    }

    @Override
    public ChatClientRequest before(ChatClientRequest chatClientRequest, AdvisorChain advisorChain) {
        String userText = chatClientRequest.prompt().getUserMessage().getText();
        String lowerCaseUserText = userText.toLowerCase();

        for (String word : this.forbiddenWords) {
            if (lowerCaseUserText.contains(word)) {
                logger.warn("请求被拒绝，因为输入中包含违禁词: '{}'", word);
                throw new IllegalArgumentException("请求失败：输入内容包含不被允许的词语。");
            }
        }

        return chatClientRequest;
    }

    @Override
    public ChatClientResponse after(ChatClientResponse chatClientResponse, AdvisorChain advisorChain) {
        return chatClientResponse;
    }

    @Override
    public int getOrder() {
        return this.order;
    }

    public ForbiddenWordsAdvisor withOrder(int order) {
        this.order = order;
        return this;
    }
}